/*
 * The MIT License
 *
 * Copyright 2014 Florian Barras.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifdef __cplusplus
extern "C"
{
#endif
#ifndef _COMMON_CONSTANTS_H
#define _COMMON_CONSTANTS_H


	/***************************************************************************
	 * INCLUDE(S)
	 **************************************************************************/

#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <math.h>


	/***************************************************************************
	 * GENERAL
	 **************************************************************************/

	/**
	 * Enables the Unicode character encoding standard.
	 */
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif

	/**************************************************************************/

	/**
	 * Uses the Standard C.
	 */
#ifndef __STDC__
#define __STDC__					0
#endif

	/**************************************************************************/

	/**
	 * Defines the architecture to be considered.
	 */
#define _32_BITS
	/* #define _64_BITS */

	/**************************************************************************/

	/**
	 * Uses the wide characters.
	 */
	/* #define _WIDE_STRING */

	/**************************************************************************/

	/**
	 * Enables the verification of the arguments.
	 */
#define _CHECK_MODE

	/**************************************************************************/

	/**
	 * Enables debug information.
	 */
	/* #define _TEST_MODE */

	/**
	 * Enables warning information.
	 */
#define _WARN_MODE


	/***************************************************************************
	 * COMMON
	 **************************************************************************/

	/**
	 * Defines the string of the NULLs.
	 */
#define _NULL_STRING				_S("NULL")

	/**************************************************************************/

	/**
	 * Defines the format specifier of the pointers.
	 */
#define _POINTER_FORMAT				_S("%p")

	/**************************************************************************/

	/**
	 * Defines the name of the unknown structures.
	 */
#define _UNKNOWN_NAME				_S("unknown structure")

	/**
	 * Defines the type of the unknown structures.
	 */
#if defined(_32_BITS)
#define _UNKNOWN_TYPE				0L /* 32 bits */
#elif defined(_64_BITS)
#define _UNKNOWN_TYPE				0L /* 64 bits */
#endif

	/**
	 * Defines the string of the unknown structures.
	 */
#define _UNKNOWN_STRING				_S("?")

	/**************************************************************************/

	/**
	 * Defines the name of the Structures.
	 */
#define _STRUCTURE_NAME				_S("Structure")

	/**
	 * Defines the type of the Structures.
	 */
#if defined(_32_BITS)
#define _STRUCTURE_TYPE				268166434L /* 32 bits */
#elif defined(_64_BITS)
#define _STRUCTURE_TYPE				4974991948358000738L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the Structures.
	 */
#define _STRUCTURE_FORMAT			_S("%S")

	/**************************************************************************/

	/**
	 * Defines the name of the arrays of Structures.
	 */
#define _STRUCTURES_NAME			_S("array of Structures")

	/**
	 * Defines the type of the arrays of Structures.
	 */
#if defined(_32_BITS)
#define _STRUCTURES_TYPE			-1689498303L /* 32 bits */
#elif defined(_64_BITS)
#define _STRUCTURES_TYPE			7723893632854730298L /* 64 bits */
#endif

	/**************************************************************************/

	/**
	 * Defines the name of the Basic structures.
	 */
#define _BASIC_NAME					_S("Basic structure")

	/**
	 * Defines the type of the Basic structures.
	 */
#if defined(_32_BITS)
#define _BASIC_TYPE					-270351478L /* 32 bits */
#elif defined(_64_BITS)
#define _BASIC_TYPE					5119110478015111332L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the Basic structures.
	 */
#define _BASIC_FORMAT				_S("%B")

	/**************************************************************************/

#define _NOT_COMPARABLE				-1

	/**************************************************************************/

	/**
	 * Defines the name of the Comparable structures.
	 */
#define _COMPARABLE_NAME			_S("Comparable structure")

	/**
	 * Defines the type of the Comparable structures.
	 */
#if defined(_32_BITS)
#define _COMPARABLE_TYPE			-1167564821L /* 32 bits */
#elif defined(_64_BITS)
#define _COMPARABLE_TYPE			-6856122037152631185L /* 64 bits */
#endif


	/***************************************************************************
	 * I/O
	 **************************************************************************/

	/**
	 * Defines the line feeds.
	 */
#define _LINE_FEED					_C('\n')

	/**
	 * Defines the carriage returns.
	 */
#define _CARRIAGE_RETURN			_C('\r')

	/**************************************************************************/

	/**
	 * Defines the character introducing the format specifiers.
	 */
#define _FORMAT_SPECIFIER			_C('%')

	/**************************************************************************/

	/**
	 * Defines the name of the files.
	 */
#define _FILE_NAME					_S("file")

	/**************************************************************************/

	/**
	 * Defines the name of the I/O Messages.
	 */
#define _IO_MESSAGE_NAME			_S("I/O Message")

	/**
	 * Defines the type of the I/O Messages.
	 */
#if defined(_32_BITS)
#define _IO_MESSAGE_TYPE			385987721L /* 32 bits */
#elif defined(_64_BITS)
#define _IO_MESSAGE_TYPE			343020474024623861L /* 64 bits */
#endif

	/**************************************************************************/

	/**
	 * Defines the name of the arrays of I/O Messages.
	 */
#define _IO_MESSAGES_NAME			_S("array of I/O Messages")

	/**
	 * Defines the type of the arrays of I/O Messages.
	 */
#if defined(_32_BITS)
#define _IO_MESSAGES_TYPE			-1479357451L /* 32 bits */
#elif defined(_64_BITS)
#define _IO_MESSAGES_TYPE			-262957866591864927L /* 64 bits */
#endif


	/***************************************************************************
	 * ITERABLE
	 **************************************************************************/

	/**
	 * Defines the factor that shifts the required number of elements to
	 * allocate (in order to anticipate future increase).
	 */
#define _RESIZE_FACTOR				3

	/**************************************************************************/

	/**
	 * Defines the name of the Iterators.
	 */
#define _ITERATOR_NAME				_S("Iterator")

	/**
	 * Defines the type of the Iterators.
	 */
#if defined(_32_BITS)
#define _ITERATOR_TYPE				-238741008L /* 32 bits */
#elif defined(_64_BITS)
#define _ITERATOR_TYPE				7998456870033067090L /* 64 bits */
#endif

	/**
	 * Defines the default Iterator.
	 */
#define _ITERATOR_DEFAULT			Iterator_create(0, _UNKNOWN_TYPE, 0, NULL, Iterator_next)

	/**************************************************************************/

	/**
	 * Defines the name of the Iterable structures.
	 */
#define _ITERABLE_NAME				_S("Iterable structure")

	/**
	 * Defines the type of the Iterable structures.
	 */
#if defined(_32_BITS)
#define _ITERABLE_TYPE				-1599987989L /* 32 bits */
#elif defined(_64_BITS)
#define _ITERABLE_TYPE				-5966621408067176849L /* 64 bits */
#endif

	/**************************************************************************/

	/**
	 * Defines the name of the Collections.
	 */
#define _COLLECTION_NAME			_S("Collection")

	/**
	 * Defines the type of the Collections.
	 */
#if defined(_32_BITS)
#define _COLLECTION_TYPE			-1700966664L /* 32 bits */
#elif defined(_64_BITS)
#define _COLLECTION_TYPE			7634734103968427758L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the Collections.
	 */
#define _COLLECTION_FORMAT			_S("%S")

	/**************************************************************************/

	/**
	 * Defines the name of the Lists.
	 */
#define _LIST_NAME					_S("List")

	/**
	 * Defines the type of the Lists.
	 */
#if defined(_32_BITS)
#define _LIST_TYPE					805313283L /* 32 bits */
#elif defined(_64_BITS)
#define _LIST_TYPE					8286623314362575348L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the Lists.
	 */
#define _LIST_FORMAT				_S("%S")

	/**************************************************************************/

	/**
	 * Defines the name of the Arrays.
	 */
#define _ARRAY_NAME					_S("Array")

	/**
	 * Defines the type of the Arrays.
	 */
#if defined(_32_BITS)
#define _ARRAY_TYPE					7833849L /* 32 bits */
#elif defined(_64_BITS)
#define _ARRAY_TYPE					1962937303161L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the Array.
	 */
#define _ARRAY_FORMAT				_S("%A")

	/**************************************************************************/

	/**
	 * Defines the name of the arrays of Arrays.
	 */
#define _ARRAYS_NAME				_S("array of Arrays")

	/**
	 * Defines the type of the arrays of Arrays.
	 */
#if defined(_32_BITS)
#define _ARRAYS_TYPE				1604959883L /* 32 bits */
#elif defined(_64_BITS)
#define _ARRAYS_TYPE				7408582305883676807L /* 64 bits */
#endif


	/***************************************************************************
	 * MATH
	 **************************************************************************/

#define _EPSILON					LDBL_EPSILON


	/***************************************************************************
	 * TIME
	 **************************************************************************/

	/**
	 * Defines the number of clock ticks per millisecond.
	 */
#define _CLOCKS_PER_MSEC			((real) CLOCKS_PER_SEC / 1000.)

	/**************************************************************************/

	/**
	 * Defines the name of the Times.
	 */
#define _TIME_NAME					_S("Time")

	/**
	 * Defines the type of the Times.
	 */
#if defined(_32_BITS)
#define _TIME_TYPE					-805299341L /* 32 bits */
#elif defined(_64_BITS)
#define _TIME_TYPE					7854277750135007973L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the times.
	 */
#if defined(__GNUC__)
#define _TIME_FORMAT				_S("%T")
#elif defined(_MSC_VER)
#define _TIME_FORMAT				_S("%X")
#else
#define _TIME_FORMAT				_S("%T")
#endif

	/**
	 * Defines the format specifier of the date times.
	 */
#if defined(__GNUC__)
#define _DATE_TIME_FORMAT			_S("%F %T")
#elif defined(_MSC_VER)
#define _DATE_TIME_FORMAT			_S("%x %X")
#else
#define _DATE_TIME_FORMAT			_S("%F %T")
#endif

	/**************************************************************************/

	/**
	 * Defines the name of the arrays of Times.
	 */
#define _TIMES_NAME					_S("array of Times")

	/**
	 * Defines the type of the arrays of Times.
	 */
#if defined(_32_BITS)
#define _TIMES_TYPE					-32064055L /* 32 bits */
#elif defined(_64_BITS)
#define _TIMES_TYPE					-9005049474081278511L /* 64 bits */
#endif


	/***************************************************************************
	 * TYPE
	 **************************************************************************/

	/**
	 * Defines the name of the booleans.
	 */
#define _BOOLEAN_NAME				_S("boolean")

	/**
	 * Defines the type of the booleans.
	 */
#if defined(_32_BITS)
#define _BOOLEAN_TYPE				438529326L /* 32 bits */
#elif defined(_64_BITS)
#define _BOOLEAN_TYPE				15675400930500718L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the booleans.
	 */
#define _BOOLEAN_FORMAT				_S("%b")

	/**
	 * Defines the false value for the booleans.
	 */
#define _FALSE						0

	/**
	 * Defines the true value for the booleans.
	 */
#define _TRUE						1

	/**
	 * Defines the string of {@code _FALSE}.
	 */
#define _FALSE_STRING				_S("false")

	/**
	 * Defines the string of {@code _TRUE}.
	 */
#define _TRUE_STRING				_S("true")

	/**************************************************************************/

	/**
	 * Defines the name of the arrays of booleans.
	 */
#define _BOOLEANS_NAME				_S("array of booleans")

	/**
	 * Defines the type of the arrays of booleans.
	 */
#if defined(_32_BITS)
#define _BOOLEANS_TYPE				-582562266L /* 32 bits */
#elif defined(_64_BITS)
#define _BOOLEANS_TYPE				2469613196631256235L /* 64 bits */
#endif

	/**************************************************************************/

	/**
	 * Defines the name of the characters.
	 */
#define _CHARACTER_NAME				_S("character")

	/**
	 * Defines the type of the characters.
	 */
#if defined(_32_BITS)
#define _CHARACTER_TYPE				-27223692L /* 32 bits */
#elif defined(_64_BITS)
#define _CHARACTER_TYPE				-8788439263639338892L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the characters.
	 */
#define _CHARACTER_FORMAT			_S("%c")

	/**
	 * Defines the minimum value of the characters.
	 */
#ifdef _WIDE_STRING
#define _CHARACTER_MIN				WCHAR_MIN
#else
#define _CHARACTER_MIN				CHAR_MIN
#endif

	/**
	 * Defines the maximum value of the characters.
	 */
#ifdef _WIDE_STRING
#define _CHARACTER_MAX				WCHAR_MAX
#else
#define _CHARACTER_MAX				CHAR_MAX
#endif

	/**************************************************************************/

	/**
	 * Defines the name of the arrays of characters.
	 */
#define _CHARACTERS_NAME			_S("array of characters")

	/**
	 * Defines the type of the arrays of characters.
	 */
#if defined(_32_BITS)
#define _CHARACTERS_TYPE			-1211079616L /* 32 bits */
#elif defined(_64_BITS)
#define _CHARACTERS_TYPE			6553243037010994747L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the arrays of characters.
	 */
#define _CHARACTERS_FORMAT			_S("%s")

	/**************************************************************************/

	/**
	 * Defines the name of the digits.
	 */
#define _DIGIT_NAME					_S("digit")

	/**
	 * Defines the type of the digits.
	 */
#if defined(_32_BITS)
#define _DIGIT_TYPE					7273908L /* 32 bits */
#elif defined(_64_BITS)
#define _DIGIT_TYPE					1810818195572L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the digits.
	 */
#define _DIGIT_FORMAT				_S("%d")

	/**
	 * Defines the minimum value of the digits.
	 */
#define _DIGIT_MIN					0

	/**
	 * Defines the maximum value of the digits.
	 */
#define _DIGIT_MAX					UCHAR_MAX

	/**************************************************************************/

	/**
	 * Defines the name of the arrays of digits.
	 */
#define _DIGITS_NAME				_S("array of digits")

	/**
	 * Defines the type of the arrays of digits.
	 */
#if defined(_32_BITS)
#define _DIGITS_TYPE				1459435659L /* 32 bits */
#elif defined(_64_BITS)
#define _DIGITS_TYPE				7404500591823675527L /* 64 bits */
#endif

	/**************************************************************************/

	/**
	 * Defines the name of the integers.
	 */
#define _INTEGER_NAME				_S("integer")

	/**
	 * Defines the type of the integers.
	 */
#if defined(_32_BITS)
#define _INTEGER_TYPE				440913330L /* 32 bits */
#elif defined(_64_BITS)
#define _INTEGER_TYPE				15539491731988594L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the integers.
	 */
#define _INTEGER_FORMAT				_S("%i")

	/**
	 * Defines the minimum value of the integers.
	 */
#if __STDC__
#define _INTEGER_MIN				LONG_MIN
#else
#define _INTEGER_MIN				LLONG_MIN
#endif

	/**
	 * Defines the maximum value of the integers.
	 */
#if __STDC__
#define _INTEGER_MAX				LONG_MAX
#else
#define _INTEGER_MAX				LLONG_MAX
#endif

	/**************************************************************************/

	/**
	 * Defines the name of the arrays of integers.
	 */
#define _INTEGERS_NAME				_S("array of integers")

	/**
	 * Defines the type of the arrays of integers.
	 */
#if defined(_32_BITS)
#define _INTEGERS_TYPE				1803562790L /* 32 bits */
#elif defined(_64_BITS)
#define _INTEGERS_TYPE				-7905976142588138325L /* 64 bits */
#endif

	/**************************************************************************/

	/**
	 * Defines the name of the natural numbers.
	 */
#define _NATURAL_NAME				_S("natural number")

	/**
	 * Defines the type of the natural numbers.
	 */
#if defined(_32_BITS)
#define _NATURAL_TYPE				-1497620190L /* 32 bits */
#elif defined(_64_BITS)
#define _NATURAL_TYPE				-8424211561607063880L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the natural numbers.
	 */
#define _NATURAL_FORMAT				_S("%n")

	/**
	 * Defines the minimum value of the natural numbers.
	 */
#define _NATURAL_MIN				0
	/**
	 * Defines the maximum value of the natural numbers.
	 */
#define _NATURAL_MAX				SIZE_MAX

	/**************************************************************************/

	/**
	 * Defines the name of the arrays of natural numbers.
	 */
#define _NATURALS_NAME				_S("array of natural numbers")

	/**
	 * Defines the type of the arrays of natural numbers.
	 */
#if defined(_32_BITS)
#define _NATURALS_TYPE				874773334L /* 32 bits */
#elif defined(_64_BITS)
#define _NATURALS_TYPE				5965406374232622482L /* 64 bits */
#endif

	/**************************************************************************/

	/**
	 * Defines the name of the real numbers.
	 */
#define _REAL_NAME					_S("real number")

	/**
	 * Defines the type of the real numbers.
	 */
#if defined(_32_BITS)
#define _REAL_TYPE					980147580L /* 32 bits */
#elif defined(_64_BITS)
#define _REAL_TYPE					-4168343457386165616L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the real numbers.
	 */
#define _REAL_FORMAT				_S("%r")

	/**
	 * Defines the minimum value of the real numbers.
	 */
#define _REAL_MIN					-LDBL_MAX

	/**
	 * Defines the maximum value of the real numbers.
	 */
#define _REAL_MAX					LDBL_MAX

	/**
	 * Defines the number of decimals to be displayed.
	 */
#define _DECIMALS_NUMBER				_S("4")

	/**
	 * Defines the real number from which the engineering notation is used.
	 */
#define _ENGINEERING_NOTATION_FROM	1E10

	/**************************************************************************/

	/**
	 * Defines the name of the arrays of real numbers.
	 */
#define _REALS_NAME					_S("array of real numbers")

	/**
	 * Defines the type of the arrays of real numbers.
	 */
#if defined(_32_BITS)
#define _REALS_TYPE					-1166258983L /* 32 bits */
#elif defined(_64_BITS)
#define _REALS_TYPE					2925876010904038195L /* 64 bits */
#endif

	/**************************************************************************/

	/**
	 * Defines the name of the strings.
	 */
#define _STRING_NAME				_S("string")

	/**
	 * Defines the type of the strings.
	 */
#if defined(_32_BITS)
#define _STRING_TYPE				-536401687L /* 32 bits */
#elif defined(_64_BITS)
#define _STRING_TYPE				7926335351986138663L /* 64 bits */
#endif
	/**
	 * Defines the format specifier of the strings.
	 */
#define _STRING_FORMAT				_S("%s")

	/**
	 * Defines the maximum size of the strings.
	 */
#define _STRING_SIZE				256

	/**
	 * Defines the maximum length of the strings.
	 */
#define _STRING_LENGTH_MAX			255 /* _STRING_SIZE - 1 */

	/**
	 * Defines the end of the strings.
	 */
#define _STRING_END					_C('\0')

	/**
	 * Defines the empty string.
	 */
#define _STRING_EMPTY				_S("")

	/**************************************************************************/

	/**
	 * Defines the name of the arrays of strings.
	 */
#define _STRINGS_NAME				_S("array of strings")

	/**
	 * Defines the type of the arrays of strings.
	 */
#if defined(_32_BITS)
#define _STRINGS_TYPE				-181233542L /* 32 bits */
#elif defined(_64_BITS)
#define _STRINGS_TYPE				-7825345672083828333L /* 64 bits */
#endif

	/**************************************************************************/

	/**
	 * Defines the name of the Numbers.
	 */
#define _NUMBER_NAME				_S("Number")

	/**
	 * Defines the type of the Numbers.
	 */
#if defined(_32_BITS)
#define _NUMBER_TYPE				1342637888L /* 32 bits */
#elif defined(_64_BITS)
#define _NUMBER_TYPE				7277817005702663634L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the Numbers.
	 */
#define _NUMBER_FORMAT				_S("%N")

	/**
	 * Defines the maximum length of the Numbers (arrays of digits).
	 */
#if defined(_32_BITS)
#define _NUMBER_LENGTH_MAX			32
#elif defined(_64_BITS)
#define _NUMBER_LENGTH_MAX			64
#endif

	/**
	 * Defines the maximum base of the Numbers.
	 */
#define _NUMBER_BASE_MAX			36

	/**************************************************************************/

	/**
	 * Defines the name of the arrays of Numbers.
	 */
#define _NUMBERS_NAME				_S("array of Numbers")

	/**
	 * Defines the type of the arrays of Numbers.
	 */
#if defined(_32_BITS)
#define _NUMBERS_TYPE				-1513657449L /* 32 bits */
#elif defined(_64_BITS)
#define _NUMBERS_TYPE				-8762079552042635021L /* 64 bits */
#endif

	/**************************************************************************/

	/**
	 * Defines the name of the Objects.
	 */
#define _OBJECT_NAME				_S("Object")

	/**
	 * Defines the type of the Objects.
	 */
#if defined(_32_BITS)
#define _OBJECT_TYPE				805730202L /* 32 bits */
#elif defined(_64_BITS)
#define _OBJECT_TYPE				7133701816351501620L /* 64 bits */
#endif

	/**
	 * Defines the format specifier of the Objects.
	 */
#define _OBJECT_FORMAT				_S("%O")

	/**************************************************************************/

	/**
	 * Defines the name of the arrays of Objects.
	 */
#define _OBJECTS_NAME				_S("array of Objects")

	/**
	 * Defines the type of the arrays of Objects.
	 */
#if defined(_32_BITS)
#define _OBJECTS_TYPE				-977072885L /* 32 bits */
#elif defined(_64_BITS)
#define _OBJECTS_TYPE				-9194424566182301677L /* 64 bits */
#endif


#endif /* _COMMON_CONSTANTS_H */
#ifdef __cplusplus
}
#endif
